'''
Created on Feb 25, 2011

@author: Jon McGrath, skeleton by Chris
'''

import os
import shutil
import StyloInterface
import XMLHandler

class FileHandler:
    '''
    This class directly accesses the file system and keeps track of every external file that is used in the application
    '''

    def __init__(self, styloInterface):
        '''
        Constructor
        '''
        self.pathNameProject = NotImplemented  # the file path for the project file to be saved or loaded
        self.pathNameCorpus = NotImplemented  # the filepath for the corpus folder to be saved or loaded
        self.corpus = NotImplemented  # a list of the various documents that will be submitted for the sample to be analyzed against
        
        self.xmlh = XMLHandler.XMLHandler()
        self.hasLoadedProject = False
        if styloInterface is None:
            self.styloInterface = StyloInterface.StyloInterface()
        else:
            self.styloInterface = styloInterface
        
    def loadCorpusFiles(self,filenames):
        """ 
        This method does something with all the corpus files (displays them?).  Nothing right now except prints names.
        """
        #print 'FileHandler.loadCorpus(self,filenames)'
        for filename in filenames:
            print filename
        return NotImplemented
        
    def loadCorpusFilesFromFolder(self,folder,recursive):
        """
        This method returns a corpus from a folder.  In other words, it returns
        all of the documents in that folder, which should be the corpus folder.
        NOTE: THIS FUNCTIONALITY EXTENDS ONLY AS FAR AS loadCorpusFiles.  CURRENTLY,
        IT DOESN'T ACTUALLY DO ANYTHING OTHER THAN PRINT OUT THE FILENAMES.
        """
        return self.loadCorpusFiles(self.getFilesInFolder(folder,recursive))
        
    def submit(self, document):
        """ 
        This method submits the document and the corpus to StyloInterface and assigns the data accordingly 
        """
        self.styloInterface.submit(document, self.corpus)
        pass
        
    def clearProjectSettings(self):
        self.xmlh.clearSubElements()
        
    def saveProject(self,filename):
        """ 
        This method attempts to save the user project for later use or retrieval 
        """
        #If the file doesn't exist or we are overwriting a file, then create a blank file there.
        if not os.path.exists(filename) or not self.hasLoadedProject:
            self.writeText(filename,self.xmlh.defaultXML(filename))
            self.xmlh.loadFromFile(filename)
        else:
            self.xmlh.writeToFile(filename)
        return True
    
    def writeText(self,filename,text):
        """
        This method saves the text to a given filename
        """
        f = open(filename,'w')
        f.write(text)
        f.close()
        
    def readText(self,documentFilename):
        f = open(documentFilename,'r')
        text = f.read()
        f.close()
        return text        
        
    def mkdir(self,pathName):
        if not os.path.exists(pathName):
            return os.mkdir(pathName)
        return False
    
    def rmdir(self,pathName):
        for path in (os.path.join(pathName,f) for f in os.listdir(pathName)):
            if os.path.isdir(path):
                self.rmdir(path)
            else:
                os.unlink(path)
        os.rmdir(pathName)
    
    def copyFile(self,filename,newpath):
        shutil.copy(filename,newpath)
        
    def copyFolder(self,source,dest):
        return shutil.copytree(source,dest)
    
    def loadProject(self, filename):
        """ 
        This method loads a project file and parses it and restores an old project state for the user 
        """
        self.filename = filename
        self.xmlh.loadFromFile(filename)
        self.xmlh.printXML()
        self.hasLoadedProject=True
        return self.xmlh
    
    def getProjectSetting(self,settingName):
        return self.xmlh.getElementText(settingName)
    
    def writeProjectSetting(self,settingName,settingValue):
        return self.xmlh.setSubElement(settingName,settingValue)
    
    def getProjectFilename(self):
        return self.xmlh.getFilename()
    
    def defaultXML(self):
        return self.xmlh.defaultXML()
    
    def getCWD(self):
        return os.getcwd()
    
    def getPathFromFilename(self, filename):
        return os.path.dirname(filename)
    
    def fileExists(self,filename):
        return os.path.exists(filename) and os.path.isfile(filename)
    
    def getExistingFile(self,frameController,filename,initialDirectory=None):
        if self.fileExists(filename):
            return filename
        frameController.showWarning(
                                 "Selecting file",
                                 "The document (%s) does not exist, please browse for it." % filename
                                 )
        if initialDirectory is None:
            initialDirectory=self.getCWD()+"/users"
        return frameController.promptOpenFile(initialDirectory)
    
    def getExistingFolder(self,frameController,pathname,initialDirectory=None):
        if os.path.isdir(pathname):
            return pathname
        frameController.showWarning(
                                 "Selecting folder",
                                 "The folder (%s) does not exist, please browse for it." % pathname
                                 )
        if initialDirectory is None:
            initialDirectory=self.getCWD()
        return frameController.promptOpenFolder(initialDirectory)
    
    def getFilesInFolder(self,folder,recursive):
        files=[ os.path.join(folder,file) for file in os.listdir(folder) if not os.path.isdir(os.path.join(folder, file)) ]
        if recursive:
            for file in os.listdir(folder):
                if os.path.isdir(os.path.join(folder, file)):
                    files.extend(self.__getFilesInFolder(folder+"/"+file, recursive))
        return files
    
    def getSubfolders(self,folder,recursive=False,getBaseNames=False):
        subfolders=[]
        if  folder[len(folder)-1:]!="/" and folder[len(folder)-1:]!="\\":
            folder+="/"
        for file in os.listdir(folder):
            fullpath=folder+file+"/"
            if os.path.isdir(fullpath):
                if getBaseNames:
                    subfolders.append(file)
                else:
                    subfolders.append(fullpath)
                if recursive:
                    subfolders.extend(self.getSubfolders(fullpath, recursive))
        return subfolders
            